/**
*	Header: camera.h
*	
*	This header contains the declaration and definition for the camera class, an object use in
*	rendering by the world class' draw() method
*	
*/

#pragma once

#include <fstream>
#include <utility>

class Camera { // Assumes top left corner of absolute map is 0,0. Revise if untrue.
public:
	Camera();
	Camera(const unsigned int x, const unsigned int y);
	Camera(const std::pair <unsigned int,unsigned int>& xy);

	void resize(const unsigned int x, const unsigned int y);

	// Check if a tile is visible in-camera.
	const bool isVisible(const unsigned int x, const unsigned int y);

	// Move top left corner. Does not account for map maximums.
	void moveTo(const unsigned int x, const unsigned int y);

	// These functions do not take into account the camera's viewport going "off edge". USE WITH CAUTION.
	void centerOn(const unsigned int x, const unsigned int y);

	// Takes into account the top left corner edge but not the rest! Must manually account for going beyond the maximums of map. Still preferable.
	void centerOn_s(const unsigned int x, const unsigned int y);

	const std::pair <unsigned int,unsigned int> * const getPosition () {return &position;}
	const unsigned int Camera::getPositionX () {return position.first;}
	const unsigned int Camera::getPositionY () {return position.second;}

	const std::pair <unsigned int,unsigned int> * const getSize () {return &size;}
	const unsigned int Camera::getWidth () {return size.first;}
	const unsigned int Camera::getHeight () {return size.second;}

	const std::pair <int,int> getOffset (const unsigned int x, const unsigned int y);
	const int Camera::getOffsetX (const unsigned int x);
	const int Camera::getOffsetY (const unsigned int y);

private:
	std::pair <unsigned int,unsigned int> position; // Abs. pos. of top left corner
	std::pair <unsigned int,unsigned int> size; // Size in tiles
};

Camera::Camera() {
	std::cerr << "Camera object created with no initial position or size!\n";
}

Camera::Camera(const std::pair<unsigned int,unsigned int>& xy) {
	size = xy;
}

Camera::Camera(const unsigned int x, const unsigned int y) {
	size = std::make_pair(x,y);
}

const bool Camera::isVisible(const unsigned int x, const unsigned int y) {
	if (x < position.first) return false;
	else if (x > position.first+size.first) return false;
	else if (y < position.second) return false;
	else if (y > position.second+size.second) return false;
	else return true;
}

void Camera::resize(const unsigned int x, const unsigned int y) {
	size = std::make_pair(x,y);
}

void Camera::moveTo(const unsigned int x, const unsigned int y) {
	position = std::make_pair(x,y);
}

void Camera::centerOn(const unsigned int x, const unsigned int y) {
	position.first = x-(size.first/2);
	position.second = y-(size.second/2);
}

void Camera::centerOn_s(const unsigned int x, const unsigned int y) {
	if (x >= size.first/2)
		position.first = x-size.first/2;
	else
		position.first = 0;
	if (y >= size.second/2)
		position.second = y-size.second/2;
	else
		position.second = 0;
}

const std::pair <int,int> Camera::getOffset (const unsigned int x, const unsigned int y) {
	return std::make_pair(position.first-x,position.second-y);
}

const int Camera::getOffsetX (const unsigned int x) {
	return position.first-x;
}

const int Camera::getOffsetY (const unsigned int y) {
	return position.second-y;
}